<template>
  <div class="hot-search-cloud">
    <!-- 筛选条件 -->
    <div class="filter-container">
      <div class="time-filter">
        <span class="filter-label">热搜热榜</span>
        <div class="filter-controls">
          <!-- 平台选择 -->
          <el-select
            v-model="platform"
            placeholder="选择平台"
            @change="handlePlatformChange"
            class="platform-select"
          >
            <el-option label="抖音" value="1"></el-option>
            <el-option label="微信" value="2"></el-option>
          </el-select>

          <!-- 地域选择 -->
          <el-select
            v-model="region"
            placeholder="选择地域"
            @change="handleRegionChange"
            class="region-select"
          >
            <el-option label="同城" value="0"></el-option>
            <el-option label="全国" value="1"></el-option>
          </el-select>

          <el-date-picker
            v-model="timeRange"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
    
            @change="handleTimeChange"
            class="compact-date-picker"
          />
          <el-button type="primary" @click="refreshData" class="refresh-btn">
            <i class="el-icon-refresh"></i>
            刷新
          </el-button>
        </div>
      </div>
    </div>

    <!-- 词云容器 -->
    <div class="word-cloud-container">
      <div ref="wordCloudRef" class="word-cloud-canvas"></div>
    </div>
  </div>
</template>

<script>
import * as d3 from "d3";
import "@/styles/time.scss";
import { currentPOST } from "api/modules";

export default {
  name: "HotSearchCloud",
  data() {
    return {
      timeRange: [],
      hotWords: [],
      animationFrame: null,
      isAnimating: false,
      svg: null,
      animationCompleted: false,
      // 平台选择：1-抖音，2-微信
      platform: "1",
      // 地域选择：0-同城，1-全国
      region: "0"
    };
  },
  mounted() {
    this.getCloudData();
    window.addEventListener("resize", this.handleResize);
  },
  beforeDestroy() {
    this.stopAnimation();
    window.removeEventListener("resize", this.handleResize);
  },
  methods: {
    getCloudData() {
      const params = {
        isCity: this.region, // 0-同城，1-全国
        type: this.platform   // 1-抖音，2-微信
      };
      
      currentPOST("centerCenterClues", params)
        .then((res) => {
          if (res.code === 0) {
            // 处理API返回的数据格式，只取前20条
            this.processHotWordsData(res.data || []);
            this.$nextTick(() => {
              this.initWordCloud();
            });
          } else {
            this.$Message({
              text: res.msg,
              type: "warning",
            });
          }
        })
        .catch((error) => {
          console.error("热搜数据请求失败:", error);
        });
    },

    // 处理热搜数据
    processHotWordsData(data) {
      // 只取前20条数据
      const limitedData = data.slice(0, 20);
      
      // 根据在榜时间计算热度值，并生成颜色
      this.hotWords = limitedData.map((item, index) => {
        // 使用在榜时间作为热度值，如果没有在榜时间则使用排名
        let heatValue = parseInt(item.onListTime) || (50 - index);
        // 确保热度值在合理范围内
        heatValue = Math.max(10, Math.min(heatValue, 100));

        return {
          text: item.title,
          value: heatValue,
          color: this.generateColor(index, heatValue),
          url: item.url,
          topId: item.topId,
          firstInsertTime: item.firstInsertTime,
          onListTime: item.onListTime,
        };
      });
    },

    // 生成颜色 - 根据排名和热度值生成不同颜色
    generateColor(index, value) {
      const colors = [
        "#ff6b6b",
        "#ff9f43",
        "#feca57",
        "#ff9ff3",
        "#54a0ff",
        "#5f27cd",
        "#00d2d3",
        "#10ac84",
        "#4ecdc4",
        "#45b7d1",
        "#96ceb4",
        "#a29bfe",
        "#ff7979",
        "#badc58",
        "#f9ca24",
        "#eb4d4b",
        "#6c5ce7",
        "#00cec9",
        "#fd79a8",
        "#e17055",
      ];

      // 根据热度值选择颜色，热度高的用暖色，低的用冷色
      if (value > 80) return colors[0]; // 红色 - 最高热度
      if (value > 60) return colors[1]; // 橙色
      if (value > 40) return colors[4]; // 蓝色
      if (value > 20) return colors[6]; // 青色
      return colors[10]; // 绿色 - 最低热度
    },

    initWordCloud() {
      const container = this.$refs.wordCloudRef;
      if (!container) return;

      const width = container.clientWidth;
      const height = container.clientHeight;

      // 清除现有内容
      d3.select(container).selectAll("*").remove();

      // 创建SVG并添加内边距
      this.svg = d3
        .select(container)
        .append("svg")
        .attr("width", width)
        .attr("height", height);

      // 创建发光效果滤镜
      const defs = this.svg.append("defs");
      const filter = defs
        .append("filter")
        .attr("id", "glow")
        .attr("x", "-50%")
        .attr("y", "-50%")
        .attr("width", "200%")
        .attr("height", "200%");

      filter
        .append("feGaussianBlur")
        .attr("in", "SourceGraphic")
        .attr("stdDeviation", "3")
        .attr("result", "blur");

      filter
        .append("feMerge")
        .selectAll("feMergeNode")
        .data(["blur", "SourceGraphic"])
        .enter()
        .append("feMergeNode")
        .attr("in", (d) => d);

      // 创建文字元素
      const texts = this.svg
        .selectAll("text")
        .data(this.hotWords)
        .enter()
        .append("text")
        .text((d) => d.text)
        .attr("font-size", (d) => this.calculateFontSize(d.value))
        .attr("font-weight", "bold")
        .attr("fill", (d) => d.color)
        .attr("text-anchor", "middle")
        .attr("dy", "0.35em")
        .style("cursor", "pointer")
        .style("opacity", 0)
        .style("filter", "url(#glow)")
        .on("mouseover", this.handleMouseOver)
        .on("mouseout", this.handleMouseOut)
        .on("click", this.handleWordClick);

      // 启动一次性入场动画
      this.startEntranceAnimation(texts, width, height);
    },

    startEntranceAnimation(texts, width, height) {
      this.isAnimating = true;
      this.animationCompleted = false;

      // 预计算所有词的最终位置（带边界检测的网格布局）
      const positions = this.calculateGridPositionsWithBounds(width, height);

      const totalDuration = 1500; // 总动画时长1.5秒
      const startTime = Date.now();

      const animate = () => {
        if (!this.isAnimating) return;

        const currentTime = Date.now() - startTime;
        const progress = Math.min(currentTime / totalDuration, 1);

        texts.each((d, i) => {
          const text = d3.select(texts.nodes()[i]);
          const finalPos = positions[i];
          const delay = i * 30; // 每个词延迟30ms出现

          if (currentTime >= delay) {
            const wordProgress = Math.min(
              (currentTime - delay) / (totalDuration - delay),
              1
            );

            // 使用缓动函数
            const easedProgress = this.easeOutCubic(wordProgress);

            // 从中心向外扩散的动画
            const centerX = width / 2;
            const centerY = height / 2;
            const currentX = centerX + (finalPos.x - centerX) * easedProgress;
            const currentY = centerY + (finalPos.y - centerY) * easedProgress;
            const currentOpacity = easedProgress;
            const currentScale = 0.5 + 0.5 * easedProgress; // 从50%大小开始

            text
              .attr("x", currentX)
              .attr("y", currentY)
              .style("opacity", currentOpacity)
              .attr(
                "font-size",
                this.calculateFontSize(d.value) * currentScale
              );
          }
        });

        if (progress < 1) {
          this.animationFrame = requestAnimationFrame(animate);
        } else {
          this.animationCompleted = true;
          this.isAnimating = false;
        }
      };

      animate();
    },

    // 计算带边界检测的网格位置
    calculateGridPositionsWithBounds(width, height) {
      const positions = [];
      const cols = 4; // 4列
      const rows = Math.ceil(this.hotWords.length / cols);

      // 计算安全区域（留出边距）
      const margin = 40; // 边距
      const safeWidth = width - margin * 2;
      const safeHeight = height - margin * 2;

      const cellWidth = safeWidth / cols;
      const cellHeight = safeHeight / rows;

      this.hotWords.forEach((d, i) => {
        const colIndex = i % cols;
        const rowIndex = Math.floor(i / cols);

        // 在格子内随机位置，但考虑文字宽度
        const padding = 0.2;
        const randomX = (Math.random() * (1 - 2 * padding) + padding) * cellWidth;
        const randomY = (Math.random() * (1 - 2 * padding) + padding) * cellHeight;

        // 计算文字的大致宽度（根据字体大小和文字长度估算）
        const fontSize = this.calculateFontSize(d.value);
        const textWidth = d.text.length * fontSize * 0.6; // 估算文字宽度
        
        let x = margin + colIndex * cellWidth + randomX;
        let y = margin + rowIndex * cellHeight + randomY;

        // 边界检测和调整
        // 左边界检测
        if (x - textWidth / 2 < margin) {
          x = margin + textWidth / 2;
        }
        // 右边界检测
        if (x + textWidth / 2 > width - margin) {
          x = width - margin - textWidth / 2;
        }
        // 上边界检测
        if (y - fontSize / 2 < margin) {
          y = margin + fontSize / 2;
        }
        // 下边界检测
        if (y + fontSize / 2 > height - margin) {
          y = height - margin - fontSize / 2;
        }

        positions.push({ x, y });
      });

      return positions;
    },

    // 缓动函数
    easeOutCubic(t) {
      return 1 - Math.pow(1 - t, 3);
    },

    calculateFontSize(value) {
      // 根据热度值计算字体大小，热度高的字体大，但限制最大最小值
      const baseSize = Math.sqrt(value) * 1.5 + 10;
      return Math.max(12, Math.min(baseSize, 24)); // 限制在12-24px之间
    },

    handleMouseOver(event, d) {
      if (!this.animationCompleted) return;

      d3.select(event.currentTarget)
        .transition()
        .duration(200)
        .style(
          "filter",
          "url(#glow) drop-shadow(0 0 10px rgba(255,255,255,0.8))"
        )
        .attr("font-size", this.calculateFontSize(d.value) * 1.2); // 减小放大倍数
    },

    handleMouseOut(event, d) {
      if (!this.animationCompleted) return;

      d3.select(event.currentTarget)
        .transition()
        .duration(200)
        .style("filter", "url(#glow)")
        .attr("font-size", this.calculateFontSize(d.value));
    },

    handleWordClick(event, d) {
      if (!this.animationCompleted) return;

      // 显示热搜词详细信息
      this.$message({
        message: `热搜: ${d.text} | 排名: ${d.topId} | 在榜时间: ${d.onListTime}分钟`,
        type: "info",
        duration: 3000,
      });

      // 可选：在新标签页打开热搜链接
      if (d.url) {
        window.open(d.url, "_blank");
      }
    },

    // 平台切换
    handlePlatformChange() {
      this.refreshData();
    },

    // 地域切换
    handleRegionChange() {
      this.refreshData();
    },

    handleTimeChange() {
      this.refreshData();
    },

    refreshData() {
      this.getCloudData();
    },

    stopAnimation() {
      this.isAnimating = false;
      if (this.animationFrame) {
        cancelAnimationFrame(this.animationFrame);
        this.animationFrame = null;
      }
    },

    handleResize() {
      this.stopAnimation();
      if (this.$refs.wordCloudRef) {
        this.initWordCloud();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.hot-search-cloud {
  position: relative;
  height: 85%;
  width: 100%;
  background-image: url("../../assets/img/clues/clues-center.png");
  background-size: cover;
  background-position: center center;
  position: relative;
  border-radius: 8px;
  overflow: hidden;
  margin-top: 20px;
}

.filter-container {

}

.time-filter {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .filter-label {
    color: #bae7ff;
    font-size: 22px;
    font-weight: 500;
    white-space: nowrap;
  }

  .filter-controls {
    display: flex;
    align-items: center;
    gap: 10px;
  }
}

.word-cloud-container {
  height: calc(100% - 80px);
  padding: 15px;
  position: relative;
  // 添加溢出隐藏
  overflow: hidden;
}

.word-cloud-canvas {
  width: 100%;
  height: 100%;
  position: relative;
  // 确保SVG内容不会溢出
  overflow: visible;
}

// 背景动画
.word-cloud-canvas::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: radial-gradient(
      2px 2px at 20% 30%,
      rgba(255, 255, 255, 0.3) 50%,
      transparent 100%
    ),
    radial-gradient(
      2px 2px at 40% 70%,
      rgba(255, 255, 255, 0.3) 50%,
      transparent 100%
    ),
    radial-gradient(
      2px 2px at 60% 20%,
      rgba(255, 255, 255, 0.3) 50%,
      transparent 100%
    ),
    radial-gradient(
      2px 2px at 80% 50%,
      rgba(255, 255, 255, 0.3) 50%,
      transparent 100%
    );
  animation: float 6s ease-in-out infinite;
  pointer-events: none;
}

@keyframes float {
  0%,
  100% {
    transform: translateY(0px);
    opacity: 0.2;
  }
  50% {
    transform: translateY(-5px);
    opacity: 0.4;
  }
}

// 响应式设计
@media (max-width: 768px) {
  .hot-search-cloud {
    height: 400px;
  }

  .time-filter {
    flex-direction: column;
    align-items: stretch;
    gap: 8px;

    .filter-label {
      text-align: left;
      font-size: 18px;
    }

    .filter-controls {
      justify-content: flex-end;
      flex-wrap: wrap;
    }
  }

  .word-cloud-container {
    padding: 10px;
    height: calc(100% - 70px);
  }
}

:deep(text) {
  pointer-events: all;
  user-select: none;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  transition: all 0.3s ease;
  font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
  // 确保文字不会超出
  dominant-baseline: central;
}

// 平台和地域选择器样式
::v-deep .platform-select,
::v-deep .region-select {
  width: 100px !important;
  
  .el-input__inner {
    background: rgba(5, 25, 55, 0.8) !important;
    border: 1px solid rgba(45, 82, 120, 0.8) !important;
    color: #bae7ff !important;
    font-size: 12px !important;
    height: 32px !important;
    
    &::placeholder {
      color: rgba(186, 231, 255, 0.6) !important;
    }
  }
  
  .el-select__caret {
    color: #bae7ff !important;
  }
}

// 紧凑日期选择器样式
::v-deep .compact-date-picker {
  &.el-date-editor.el-range-editor {
    width: 240px !important;
    height: 32px !important;

    .el-range-input {
      background: transparent;
      color: #bae7ff;
      font-size: 12px !important;

      &::placeholder {
        color: rgba(186, 231, 255, 0.6);
        font-size: 12px !important;
      }
    }

    .el-range-separator {
      color: #bae7ff;
      font-size: 12px !important;
      line-height: 24px !important;
    }

    .el-range__close-icon,
    .el-range__icon {
      color: #bae7ff;
      font-size: 12px !important;
    }
  }
}

// 刷新按钮样式
.refresh-btn {
  height: 32px !important;
  padding: 8px 12px !important;
  font-size: 12px !important;

  i {
    font-size: 12px !important;
  }
}

// 修复下拉选择框样式
::v-deep .el-select-dropdown {
  background: #1e3a5f !important;
  border: 1px solid rgba(45, 82, 120, 0.8) !important;
  
  .el-select-dropdown__item {
    color: #bae7ff !important;
    font-size: 12px !important;
    
    &:hover {
      background: rgba(24, 144, 255, 0.3) !important;
      color: #ffffff !important;
    }
    
    &.selected {
      background: rgba(24, 144, 255, 0.5) !important;
      color: #ffffff !important;
    }
  }
}

// 修复日期选择器下拉框样式
::v-deep .el-picker-panel {
  background: #1e3a5f !important;
  border: 1px solid rgba(45, 82, 120, 0.8) !important;
  color: #bae7ff !important;

  .el-picker-panel__icon-btn,
  .el-date-picker__header-label,
  .el-time-panel__btn {
    color: #bae7ff !important;
    font-size: 12px !important;

    &:hover {
      color: #ffffff !important;
    }
  }

  .el-date-table th {
    color: #8fc1ff !important;
    font-size: 12px !important;
  }

  .el-date-table td {
    color: #bae7ff !important;
    font-size: 12px !important;

    &.available:hover {
      color: #ffffff !important;
    }

    &.current:not(.disabled) span {
      background: #1890ff !important;
      color: #ffffff !important;
    }

    &.today span {
      color: #1890ff !important;
    }
  }
}
</style>